package com.um.jdy.mp.user.manager;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.commons.service.MobileService;
import com.um.jdy.common.member.enums.CodeKey;
import com.um.jdy.common.platform.code.LoginCode;
import com.um.jdy.common.platform.code.PartnersCode;
import com.um.jdy.common.platform.code.PlatformCode;
import com.um.jdy.common.platform.entity.po.AppPackage;
import com.um.jdy.common.platform.entity.po.Merchant;
import com.um.jdy.common.platform.entity.po.MerchantLog;
import com.um.jdy.common.platform.enums.PlatformEnum;
import com.um.jdy.common.platform.service.AppPackageService;
import com.um.jdy.common.platform.service.MerchantLogService;
import com.um.jdy.common.platform.service.MerchantService;
import com.um.jdy.mp.user.entity.dto.EditPasswordDTO;
import com.um.jdy.mp.user.entity.dto.UserBindWXDTO;
import com.um.jdy.mp.user.entity.vo.*;
import com.um.jdy.mp.user.service.SessionUserService;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.manager.BaseManager;
import com.um.springboot.starter.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 管理类：手机
 *
 * @author cs
 * 日期 2023/5/23
 * 版权所有 广州优匠科技有限公司
 */
@Component
public class UserManager extends BaseManager<MerchantService> {

    @Autowired
    SessionUserService sessionUserService;

    @Autowired
    MobileService mobileService;

    @Autowired
    MerchantLogService merchantLogService;

    @Autowired
    AppPackageService appPackageService;

    @Autowired
    WXManager wxManager;

    public Response<SigninVO> signin(String mobile, String password) {
        password = RSAUtil.simpleDecrypt(password);
        Merchant merchant = service.getEntity("mobile", mobile);
        if (merchant == null) {
            throw new ServiceException(PartnersCode.PartnersNotExist);
        }

        //校验密码
        String pwd = merchant.getPassword();
        DesEncrypter des = new DesEncrypter(DesEncrypter.CD_KEY);
        String pwd2 = des.decrypt(pwd);
        if (!password.equals(pwd2)) {
            throw new ServiceException(LoginCode.PwdError);
        }

        if(merchant.getIsEnable().equals(YesOrNo.No.name())){
            throw new ServiceException(LoginCode.AccountDisabled);
        }

        MerchantLog loginLog = new MerchantLog();
        loginLog.setPlatformMerchantId(merchant.getPlatformMerchantId());
        loginLog.setCreateTime(new Date());
        loginLog.setComId(merchant.getComId());
        merchantLogService.add(loginLog);

        StpUtil.login(merchant.getPlatformMerchantId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        SigninVO signinVO = new SigninVO();
        signinVO.setToken(tokenInfo.getTokenValue());
        signinVO.setMerchant(BeanUtil.toBean(merchant, MerchantVO.class));
        return Response.success(signinVO);
    }

    public Response signout() {
        StpUtil.logout();
        return Response.success();
    }

    public Response<MerchantVO> get() {
        Merchant merchant = sessionUserService.getTokenUser();
        return Response.success(BeanUtil.toBean(merchant, MerchantVO.class));
    }

    /**
     * 已登录用户：绑定微信
     *
     * @param bindwxDTO
     */
    public Response bindwx(UserBindWXDTO bindwxDTO) {
        MpAuthVO mpAuthVO = wxManager.getOpenId(bindwxDTO.getCode());
        MpUserVO userVO = wxManager.getMpUserinfo(mpAuthVO.getAccess_token(), mpAuthVO.getOpenid());

        Merchant exist = service.getEntity("mp_open_id",userVO.getOpenid());
        if(exist != null){//此微信已绑定其他账号
            throw new ServiceException(LoginCode.MpOpenIdExist);
        }

        Merchant merchant = new Merchant();
        merchant.setPlatformMerchantId(sessionUserService.getTokenUser().getPlatformMerchantId());
        merchant.setWxNickName(userVO.getNickname());
        merchant.setMpOpenId(userVO.getOpenid());
        merchant.setLogo(userVO.getHeadimgurl());
        boolean result = service.update(merchant);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 修改密码
     *
     * @param oldPassword
     * @param password
     * @return
     */
    public Response editPassword(String oldPassword, String password) {
        Merchant merchant = sessionUserService.getTokenUser();
        if (merchant == null) {
            throw new ServiceException(PartnersCode.PartnersNotExist);
        }

        password = RSAUtil.simpleDecrypt(password);
        oldPassword = RSAUtil.simpleDecrypt(oldPassword);

        String pwd = merchant.getPassword();
        DesEncrypter des = new DesEncrypter(DesEncrypter.CD_KEY);
        String pwd2 = des.decrypt(pwd);
        if (!oldPassword.equals(pwd2)) {
            throw new ServiceException(PartnersCode.OldPasswordError);
        }

        if (password.equals(pwd2)) {
            throw new ServiceException(PartnersCode.PwdSame);
        }

        merchant.setPassword(des.encrypt(password));
        boolean result = service.update(merchant);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 修改密码
     *
     * @param dto
     * @return
     */
    public Response editPassword(EditPasswordDTO dto) {
        Merchant merchant = service.getEntity("mobile",sessionUserService.getTokenUser().getMobile());
        if (merchant == null) {
            throw new ServiceException(PartnersCode.PartnersNotExist);
        }

        if(!mobileService.checkCode(CodeKey.EditPwd,sessionUserService.getTokenUser().getMobile(),dto.getCode())){
            throw new ServiceException(LoginCode.CodeError);
        }

        String password = RSAUtil.simpleDecrypt(dto.getNewPassword());
        String pwd = merchant.getPassword();
        DesEncrypter des = new DesEncrypter(DesEncrypter.CD_KEY);
        String pwd2 = des.decrypt(pwd);
        if (password.equals(pwd2)) {
            throw new ServiceException(PartnersCode.PwdSame);
        }

        merchant.setPassword(des.encrypt(password));
        boolean result = service.update(merchant);
        return result ? Response.success() : Response.failed();
    }

    /**
     * 修改密码
     *
     * @param id
     * @param password
     * @return
     */
    public Response editPasswordByParentId(String id, String password) {
        Merchant merchant = sessionUserService.getTokenUser();
        if (merchant == null) {
            throw new ServiceException(PartnersCode.PartnersNotExist);
        }

        if (StringUtil.equals(merchant.getIsUpdatedPwd(), PlatformEnum.UpdatedPwdType.IsUpdated.name())) {
            throw new ServiceException(LoginCode.EditPwdError);
        }

        password = RSAUtil.simpleDecrypt(password);
        DesEncrypter des = new DesEncrypter(DesEncrypter.CD_KEY);
        merchant.setPassword(des.encrypt(password));
        merchant.setIsUpdatedPwd(PlatformEnum.UpdatedPwdType.IsUpdated.name());
        boolean result = service.update(merchant);
        return result ? Response.success() : Response.failed();
    }

    public Response<PackageVO> getAppPackage(){
        AppPackage appPackage = appPackageService.getEntity("com_id",getComId());
        if(appPackage == null){
            throw new ServiceException(PlatformCode.PackageNotExist);
        }

        int days = DateUtil.daysBetween(new Date(),appPackage.getEndDate());
        PackageVO packageVO = UMBeanUtils.copyBean(appPackage,PackageVO.class);

        if(days > 30){
            packageVO.setStatus(PlatformEnum.PackageStatus.Normal.name());
        }else if(days <= 30 && days > 0){
            packageVO.setStatus(PlatformEnum.PackageStatus.Warn.name());
            packageVO.setTips("平台到期剩余<span class='remain-days'>"+days+"</span>天");
            packageVO.setActionTips("去续费");
        }else{
            packageVO.setStatus(PlatformEnum.PackageStatus.Expired.name());
            packageVO.setTips("平台已过期");
            packageVO.setActionTips("去续费");
        }

        packageVO.setDays(days);
        packageVO.setPackageName("包年");

        return Response.success(packageVO);
    }
}
